﻿#include "FITKAdaptorGeoModel.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoDelete.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoMultiDelete.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelOperImprintSolid.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelImport.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelImportFlattenAssembly.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelExport.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelOperCompound.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoPart.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelFromMesh.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementFactory.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Writer.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceIO/FITKHDF5FileTool.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"


namespace Interface
{
    bool  FITKAdaptorGeoModelDelete::readParameters()
    {
        Interface::FITKAbsGeoDelete* cmd = this->getDataObjectAs<Interface::FITKAbsGeoDelete>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        int deleteCommandID = 0;
        if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_DeleteCommandID, &deleteCommandID)) return false;
        cmd->setDeleteCommandID(deleteCommandID);
        return true;
    }
    bool FITKAdaptorGeoModelDelete::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoDelete* cmd = this->getDataObjectAs<Interface::FITKAbsGeoDelete>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool,H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if(!std::get<0>(paramGroup)) return false;

        int deleteCommandID = cmd->getDeleteCommandID();
        //写出参数
        h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_DeleteCommandID, deleteCommandID);
        return true;
    }

    bool  FITKAdaptorGeoModelMultiDelete::readParameters()
    {
        Interface::FITKAbsGeoMultiDelete* cmd = this->getDataObjectAs<Interface::FITKAbsGeoMultiDelete>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        int deleteCmdIdCount = 0;
        if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_Count, &deleteCmdIdCount)) return false;
        int* deleteCommandIDs = new int[deleteCmdIdCount];
        if (!h5tools->readGroupAttrIntArray(std::get<1>(paramGroup), FGKW_DeleteCommandIDs, deleteCommandIDs, 1, deleteCmdIdCount))
        {
            delete deleteCommandIDs;
            return false;
        }
        QList<int> ids = {};
        for (int i = 0; i < deleteCmdIdCount; i++)
        {
            ids.append(deleteCommandIDs[i]);
        }
        cmd->setDeleteCommandIDs(ids);
        delete deleteCommandIDs;
        return true;
    }
    bool FITKAdaptorGeoModelMultiDelete::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoMultiDelete* cmd = this->getDataObjectAs<Interface::FITKAbsGeoMultiDelete>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        QList<int> ids = cmd->getDeleteCommandIDs();
        int deleteCmdIdCount = ids.count();
        //写出参数
        h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_Count, deleteCmdIdCount);
        int* deleteCommandIDs = new int[deleteCmdIdCount];
        for (int i = 0; i < deleteCmdIdCount; i++)
        {
            deleteCommandIDs[i] = ids[i];
        }
        if (!h5tools->writeGroupAttrIntArray(std::get<1>(paramGroup), FGKW_DeleteCommandIDs, deleteCommandIDs, 1, deleteCmdIdCount))
        {
            delete deleteCommandIDs;
            return false;
        }
        delete deleteCommandIDs;
        return true;
    }

    bool  FITKAdaptorGeoImprintSolid::readParameters()
    {
        Interface::FITKAbsGeoModelOperImprintSolid* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelOperImprintSolid>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);

        std::string type = {};
        //int type = 0;
        double tolerance = 0;
        int count = 0;
        if (!h5tools->readGroupStr(std::get<1>(paramGroup), FGKW_Type,type)) return false;
        //if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_Type,&type)) return false;
        if (!h5tools->readGroupDouble(std::get<1>(paramGroup), FGKW_Tolerance, &tolerance)) return false;
        if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_Count, &count)) return false;

        int sourceSurfaceArray[3] = {};
        for (int i = 0; i < count; i++)
        {
            if (!h5tools->readGroupAttrIntArray(std::get<1>(paramGroup), std::to_string(i).c_str(), sourceSurfaceArray, 1, 3)) return false;
            cmd->add(Interface::VirtualShape(sourceSurfaceArray[0], sourceSurfaceArray[1], sourceSurfaceArray[2]));
        }
        QMetaEnum metaEnum = QMetaEnum::fromType<Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType>();
        Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType cmdType = (Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType)metaEnum.keyToValue(type.c_str());
       // cmd->setType(Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType(type));
        cmd->setType(Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType(cmdType));
        cmd->setTolerance(tolerance);
        return true;
    }
    bool FITKAdaptorGeoImprintSolid::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelOperImprintSolid* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelOperImprintSolid>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType type = cmd->getType();
        bool ok = false;
        Core::FITKEnumTransfer<Interface::FITKAbsGeoModelOperImprintSolid::GeoSolidOperType> enumTransfer;
        QString cmdTypeStr = enumTransfer.toString(type, ok);
        if (!ok) return false;
        //int type = cmd->getType();
        double tolerance = cmd->getTolerance();
        QList<VirtualShape> shapes = cmd->getVShapes();
        int count = shapes.size();

        //写出参数
        h5tools->writeGroupAttrStr(std::get<1>(paramGroup), FGKW_Type, cmdTypeStr.toStdString());
        //h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_Type, type);
        h5tools->writeGroupAttrDouble(std::get<1>(paramGroup), FGKW_Tolerance, tolerance);
        h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_Count, count);
        for (int i = 0; i < count; i++)
        {
            int vShape[3]{ shapes[i].CmdId, shapes[i].VirtualTopoId,shapes[i].VirtualTopoIndex };
            h5tools->writeGroupAttrIntArray(std::get<1>(paramGroup), std::to_string(i).c_str(), vShape, 1, 3);
        }
        return true;
    }

    bool  FITKAdaptorGeoModelImport::readParameters()
    {
        Interface::FITKAbsGeoModelImport* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelImport>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        std::string fileName = {};
        if (!h5tools->readGroupStr(std::get<1>(paramGroup), FGKW_FileName, fileName)) return false;
        cmd->setFileName(QString::fromStdString(fileName));
        return true;
    }
    bool FITKAdaptorGeoModelImport::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelImport* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelImport>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        QString fileName = cmd->getFileName();
        //写出参数
        h5tools->writeGroupAttrStr(std::get<1>(paramGroup), FGKW_FileName, fileName.toStdString());
        return true;
    }

    bool  FITKAdaptorGeoModelExport::readParameters()
    {
        Interface::FITKAbsGeoModelExport* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelExport>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        std::string fileName = {};
        if (!h5tools->readGroupStr(std::get<1>(paramGroup), FGKW_FileName, fileName)) return false;
        cmd->setFileName(QString::fromStdString(fileName));
        return true;
    }
    bool FITKAdaptorGeoModelExport::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelExport* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelExport>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        QString fileName = cmd->getFileName();
        //写出参数
        h5tools->writeGroupAttrStr(std::get<1>(paramGroup), FGKW_FileName, fileName.toStdString());
        return true;
    }

    bool  FITKAdaptorGeoModelCompound::readParameters()
    {
        Interface::FITKAbsGeoModelOperCompound* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelOperCompound>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        int inputCmdArray[3] = {};
        int childCmdArray[3] = {};
        int count = 0;
        if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_Count, &count)) return false;
        if (!h5tools->readGroupAttrIntArray(std::get<1>(paramGroup), FGKW_InputCmd, inputCmdArray,1,3)) return false;
        Interface::VirtualShape vShape(inputCmdArray[0], inputCmdArray[1], inputCmdArray[2]);
        QList<Interface::VirtualShape> vShapeChildList = {};
        for (int i = 0; i < count; i++)
        {
            if (!h5tools->readGroupAttrIntArray(std::get<1>(paramGroup), std::to_string(i).c_str(), childCmdArray, 1, 3)) return false;

            Interface::VirtualShape vShapeChild(childCmdArray[0], childCmdArray[1], childCmdArray[2]);
            vShapeChildList.append(vShapeChild);
        }
        cmd->setInputCmdId(vShape);
        cmd->setShapeCmdIds(vShapeChildList);
        return true;
    }
    bool FITKAdaptorGeoModelCompound::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelOperCompound* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelOperCompound>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        Interface::VirtualShape vShape = cmd->getInputCmdId();
        int inputCmdArray[3]{ vShape.CmdId,vShape.VirtualTopoId, vShape.VirtualTopoIndex };
        QList<Interface::VirtualShape> cmdIDs = cmd->getShapeCmdIds();
        int count = cmdIDs.size();
        //写出参数
        h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_Count, count);
        h5tools->writeGroupAttrIntArray(std::get<1>(paramGroup), FGKW_InputCmd, inputCmdArray,1,3);
        for (int i = 0; i < count; i++)
        {
            VirtualShape cmdID = cmdIDs[i];
            int cmdIDArray[3]{ cmdID.CmdId, cmdID.VirtualTopoId,cmdID.VirtualTopoIndex };
            h5tools->writeGroupAttrIntArray(std::get<1>(paramGroup), std::to_string(i).c_str() , cmdIDArray, 1, 3);
        }
        return true;
    }

    bool  FITKAdaptorGeoModelImportFlattenAssembly::readParameters()
    {
        Interface::FITKAbsGeoModelImportFlattenAssembly* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelImportFlattenAssembly>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        std::string fileName = {};
        if (!h5tools->readGroupStr(std::get<1>(paramGroup), FGKW_FileName, fileName)) return false;
        cmd->setFileName(QString::fromStdString(fileName));
        return true;
    }
    bool FITKAdaptorGeoModelImportFlattenAssembly::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelImportFlattenAssembly* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelImportFlattenAssembly>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;

        QString fileName = cmd->getFileName();
        //写出参数
        h5tools->writeGroupAttrStr(std::get<1>(paramGroup), FGKW_FileName, fileName.toStdString());
        return true;
    }

    bool  FITKAdaptorGeoPart::readParameters()
    {
        Interface::FITKAbsGeoPart* cmd = this->getDataObjectAs<Interface::FITKAbsGeoPart>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);

        int count = 0;
        if (!h5tools->readGroupint(std::get<1>(paramGroup), FGKW_Count, &count)) return false;
        for (int i = 0; i < count; i++)
        {
            int id = 0;
            if (!h5tools->readGroupint(std::get<1>(paramGroup), std::to_string(i).c_str(), &id)) return false;
            Interface::FITKAbsGeoCommand* comm = cmd->getDataByID(id);
            cmd->addAndUpdate(comm);
        }
        return true;
    }
    bool FITKAdaptorGeoPart::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoPart* cmd = this->getDataObjectAs<Interface::FITKAbsGeoPart>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;
        QList<FITKAbsGeoCommand*> commandList = cmd->getRootCommands();
        int count = cmd->getDataCount();
        h5tools->writeGroupAttrInt(std::get<1>(paramGroup), FGKW_Count, count);
        for (int i = 0; i < count; i++)
        {
            Interface::FITKAbsGeoCommand* comm = cmd->getDataByIndex(i);
            if (!comm) return false;
            int id = comm->getDataObjectID();
            h5tools->writeGroupAttrInt(std::get<1>(paramGroup), std::to_string(i).c_str(), id);
        }
        return true;
    }

    bool  FITKAdaptorGeoModelFromMesh::readParameters()
    {
        Interface::FITKAbsGeoModelFromMesh* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelFromMesh>();
        if (cmd == nullptr || _reader == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _reader->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //打开group
        std::tuple<bool, H5::Group> paramGroup = h5tools->openGp(*_h5Group, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false; 
        H5::Group paramGp = std::get<1>(paramGroup);
        // 读取节点数量
        int nodeCount = 0;
        if (!h5tools->readGroupint(paramGp, FGKW_NodeCount, &nodeCount)) return false;
        // 读取三角形数量
        int triCount = 0;
        if (!h5tools->readGroupint(paramGp, FGKW_TriangleCount, &triCount)) return false;
       
        QList<Core::FITKNode*> meshNodes = {};
        QList<FITKAbstractElement*> meshElements = {};

        std::function<void()> cleanUp = [&]() {
            qDeleteAll(meshNodes);
            qDeleteAll(meshElements);
        };
        // 读取节点数据
        if (nodeCount > 0) 
        {
            std::vector<int> nodeIDs = {};
            std::vector<double> coordArray = {};
            // 读取节点ID和坐标
            if (!h5tools->ReadOneDArrayDataSetInt(paramGp, FGKW_NodeIDs, nodeIDs) ||
                !h5tools->ReadOneDArrayDataSetDouble(paramGp, FGKW_NodeCoordinates, coordArray))
            {
                cleanUp();
                return false;
            }
            // 创建节点
            for (int i = 0; i < nodeCount; ++i) 
            {
                Core::FITKNode* newNode = new Core::FITKNode(nodeIDs[i], coordArray[i * 3], coordArray[i * 3 + 1], coordArray[i * 3 + 2]);
                meshNodes.append(newNode);
            }
        }
        // 读取三角形数据
        if (triCount > 0) 
        {
            std::vector<int> triNodes = {};
            // 读取三角形节点
            if (!h5tools->ReadOneDArrayDataSetInt(paramGp, FGKW_TriangleNodes, triNodes))
            {
                cleanUp();
                return false;
            }
            for (int i = 0; i < triCount; ++i) 
            {
                Interface::FITKAbstractElement* newElement = Interface::FITKElementFactory::createElement(FITKModelEnum::FITKEleType::Tri3);
                if (!newElement) 
                {
                    cleanUp();
                    return false;
                }
                newElement->setNodeID(0, triNodes[i * 3]);
                newElement->setNodeID(1, triNodes[i * 3 + 1]);
                newElement->setNodeID(2, triNodes[i * 3 + 2]);
                meshElements.append(newElement);
            }
        }
        cmd->setMesh(meshNodes, meshElements);
        cleanUp();
        return true;
    }

    bool FITKAdaptorGeoModelFromMesh::writeParameters(H5::Group &g)
    {
        Interface::FITKAbsGeoModelFromMesh* cmd = this->getDataObjectAs<Interface::FITKAbsGeoModelFromMesh>();
        if (cmd == nullptr || _writer == nullptr || _h5Group == nullptr) return false;
        IO::FITKHDF5FileTool* h5tools = _writer->getHDF5FileTool();
        if (h5tools == nullptr) return false;
        //创建group组
        std::tuple<bool, H5::Group> paramGroup = h5tools->createGp(g, FGKW_Parameter);
        if (!std::get<0>(paramGroup)) return false;
        H5::Group paramGp = std::get<1>(paramGroup);

        QHash<int, FITKAbsGeoModelFromMesh::MeshNodeCoordinates> nodeCoords = cmd->getMeshNodeCoordinates();
        QList<FITKAbsGeoModelFromMesh::MeshTri> triangles = cmd->getMeshTriangles();
        const int nodeCount = nodeCoords.size();
        const int triCount = triangles.size();
        // 写入节点和三角形数量
        if (!h5tools->writeGroupAttrInt(paramGp, FGKW_NodeCount, nodeCount) ||
            !h5tools->writeGroupAttrInt(paramGp, FGKW_TriangleCount, triCount)) return false;
        // 写入节点数据
        if (nodeCount > 0) 
        {
            std::vector<int> nodeIDs = {};
            std::vector<double> coordArray = {};
            nodeIDs.reserve(nodeCount);
            coordArray.reserve(nodeCount * 3);
            for (auto it = nodeCoords.begin(); it != nodeCoords.end(); ++it) 
            {
                nodeIDs.push_back(it.key());
                coordArray.push_back(it.value().x);
                coordArray.push_back(it.value().y);
                coordArray.push_back(it.value().z);
            }
            // 写入节点ID和坐标
            if (!h5tools->CreateOneDarrayDataSetInt(paramGp, FGKW_NodeIDs, nodeIDs) ||
                !h5tools->CreateOneDarrayDataSetDouble(paramGp, FGKW_NodeCoordinates, coordArray)) return false;
        }
        // 写入三角形数据
        if (triCount > 0) 
        {
            std::vector<int> triNodes = {};
            std::vector<double> normals = {};
            triNodes.reserve(triCount * 3);
            normals.reserve(triCount * 3);
            for (const auto& tri : triangles) 
            {
                triNodes.push_back(tri.node1);
                triNodes.push_back(tri.node2);
                triNodes.push_back(tri.node3);
                normals.push_back(tri.normal[0]);
                normals.push_back(tri.normal[1]);
                normals.push_back(tri.normal[2]);
            }
            // 写入三角形节点和法向量
            if (!h5tools->CreateOneDarrayDataSetInt(paramGp, FGKW_TriangleNodes, triNodes) ||
                !h5tools->CreateOneDarrayDataSetDouble(paramGp, FGKW_TriangleNormals, normals)) return false;
        }
        return true;
    }
}



